package com.itheima.redission;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @program: cache
 * @description: 分布式锁
 * @author: zhanghz001
 * @create: 2021-04-30 10:49
 **/
@Component
@Primary
public class ZhzRedissonDistributedLocker implements DistributedLocker {
    @Autowired
    private RedissonClient redissonClient;
    
    /**
     * lock(),拿不到lock就不罢休,不然线程就一直block
     *
     * @param lockkey
     * @return
     */
    @Override
    public RLock lock(String lockkey) {
        RLock lock = redissonClient.getLock(lockkey);
        lock.lock();
        return lock;
    }
    
    /**
     * timeout为加锁时间,单位为秒
     *
     * @param lockkey
     * @param lesstime
     * @return
     */
    @Override
    public RLock lock(String lockkey, Long lesstime) {
        RLock lock = redissonClient.getLock(lockkey);
        lock.lock(lesstime, TimeUnit.SECONDS);
        return lock;
    }
    
    /**
     * timeout为加锁时间,时间单位由timeUtil决定
     *
     * @param lockkey
     * @param lesstime
     * @param timeUtil
     * @return
     */
    @Override
    public RLock lock(String lockkey, Long lesstime, TimeUnit timeUtil) {
        RLock lock = redissonClient.getLock(lockkey);
        lock.lock(lesstime, timeUtil);
        return lock;
    }
    
    /**
     * 拿到lock就返回true,不然就是false
     * 带时间限制的trylock(),拿不到lock,就等一段时间,超时返回false
     *
     * @param lockkey
     * @param lesstime
     * @param timeUtil
     * @param timeout
     * @return
     */
    @Override
    public Boolean lock(String lockkey, Long lesstime, TimeUnit timeUtil, Long timeout) {
        RLock lock = redissonClient.getLock(lockkey);
        try {
            return lock.tryLock(timeout, lesstime, timeUtil);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }
    
    /**
     * 解锁
     *
     * @param key
     */
    @Override
    public void unlock(String key) {
        RLock lock = redissonClient.getLock(key);
        lock.unlock();
    }
    
    /**
     * 解锁
     *
     * @param rLock
     */
    @Override
    public void unlock(RLock rLock) {
        rLock.unlock();
    }
}
